# DESCRIPTION: Github actions config
# This name is key to badges in README.rst, so we use the name build
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0

name: build

on:
  push:
  pull_request:
  workflow_dispatch:
  schedule:
  - cron: '0 0 * * 0' # weekly

env:
  CI_OS_NAME: linux
  CI_COMMIT: ${{ github.sha }}
  CCACHE_COMPRESS: 1
  CCACHE_DIR: ${{ github.workspace }}/.ccache
  CCACHE_LIMIT_MULTIPLE: 0.95
  INSTALL_DIR: ${{ github.workspace }}/install
  RELOC_DIR: ${{ github.workspace }}/relloc

defaults:
  run:
    shell: bash
    working-directory: repo

concurrency:
  group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.ref || github.run_id }}
  cancel-in-progress: true

jobs:

  build:
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-22.04, ubuntu-20.04]
        compiler:
          - { cc: clang, cxx: clang++ }
          - { cc: gcc,   cxx: g++     }
        include:
          # Build GCC 10 on ubuntu-20.04
          - os: ubuntu-20.04
            compiler: { cc: gcc-10, cxx: g++-10 }
    runs-on: ${{ matrix.os }}
    name: Build | ${{ matrix.os }} | ${{ matrix.compiler.cc }}
    env:
      CI_BUILD_STAGE_NAME: build
      CI_RUNS_ON: ${{ matrix.os }}
      CC: ${{ matrix.compiler.cc }}
      CXX: ${{ matrix.compiler.cxx }}
      CACHE_BASE_KEY: build-${{ matrix.os }}-${{ matrix.compiler.cc }}
      CCACHE_MAXSIZE: 1000M # Per build matrix entry (* 5 = 5000M in total)
      VERILATOR_ARCHIVE: verilator-${{ github.sha }}-${{ matrix.os }}-${{ matrix.compiler.cc }}.tar.gz
    steps:

    - name: Checkout
      uses: actions/checkout@v4
      with:
        path: repo

    - name: Cache $CCACHE_DIR
      uses: actions/cache@v4
      env:
        CACHE_KEY: ${{ env.CACHE_BASE_KEY }}-ccache
      with:
        path: ${{ env.CCACHE_DIR }}
        key: ${{ env.CACHE_KEY }}-${{ github.sha }}
        restore-keys: |
          ${{ env.CACHE_KEY }}-

    - name: Install packages for build
      run: ./ci/ci-install.bash

    - name: Build
      run: ./ci/ci-script.bash

    - name: Tar up repository
      working-directory: ${{ github.workspace }}
      run: tar --posix -c -z -f ${{ env.VERILATOR_ARCHIVE }} repo

    - name: Upload tar archive
      uses: actions/upload-artifact@v4
      with:
        path: ${{ github.workspace }}/${{ env.VERILATOR_ARCHIVE }}
        name: ${{ env.VERILATOR_ARCHIVE }}


  test:
    needs: build
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-22.04, ubuntu-20.04]
        compiler:
          - { cc: clang, cxx: clang++ }
          - { cc: gcc,   cxx: g++     }
        reloc: [0]
        suite: [dist-vlt-0, dist-vlt-1, dist-vlt-2, dist-vlt-3, vltmt-0, vltmt-1]
        include:
          # Test with GCC 10 on ubuntu-20.04
          - {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, suite: dist-vlt-0}
          - {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, suite: dist-vlt-1}
          - {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, suite: dist-vlt-2}
          - {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, suite: dist-vlt-3}
          - {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, suite: vltmt-0}
          - {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, suite: vltmt-1}
          # Test relocated installation - on most common platform only
          - {os: ubuntu-22.04, compiler: { cc: gcc, cxx: g++ }, reloc: 1, suite: dist-vlt-0}
          - {os: ubuntu-22.04, compiler: { cc: gcc, cxx: g++ }, reloc: 1, suite: dist-vlt-1}
          - {os: ubuntu-22.04, compiler: { cc: gcc, cxx: g++ }, reloc: 1, suite: dist-vlt-2}
          - {os: ubuntu-22.04, compiler: { cc: gcc, cxx: g++ }, reloc: 1, suite: dist-vlt-3}
          - {os: ubuntu-22.04, compiler: { cc: gcc, cxx: g++ }, reloc: 1, suite: vltmt-0}
          - {os: ubuntu-22.04, compiler: { cc: gcc, cxx: g++ }, reloc: 1, suite: vltmt-1}
    runs-on: ${{ matrix.os }}
    name: Test | ${{ matrix.os }} | ${{ matrix.compiler.cc }} | ${{ matrix.reloc && 'reloc | ' || '' }} ${{ matrix.suite }}
    env:
      CI_BUILD_STAGE_NAME: test
      CI_RUNS_ON: ${{ matrix.os }}
      CI_RELOC: ${{ matrix.reloc }}
      CC: ${{ matrix.compiler.cc }}
      CXX: ${{ matrix.compiler.cxx }}
      CACHE_BASE_KEY: test-${{ matrix.os }}-${{ matrix.compiler.cc }}-${{ matrix.reloc }}-${{ matrix.suite }}
      CCACHE_MAXSIZE: 100M # Per build per suite (* 5 * 5 = 2500M in total)
      VERILATOR_ARCHIVE: verilator-${{ github.sha }}-${{ matrix.os }}-${{ matrix.compiler.cc }}.tar.gz
    steps:

    - name: Download tar archive
      uses: actions/download-artifact@v4
      with:
        name: ${{ env.VERILATOR_ARCHIVE }}
        path: ${{ github.workspace }}

    - name: Unpack tar archive
      working-directory: ${{ github.workspace }}
      run: tar -x -z -f ${{ env.VERILATOR_ARCHIVE }}

    - name: Cache $CCACHE_DIR
      uses: actions/cache@v4
      env:
        CACHE_KEY: ${{ env.CACHE_BASE_KEY }}-ccache2
      with:
        path: ${{ env.CCACHE_DIR }}
        key: ${{ env.CACHE_KEY }}-${{ github.sha }}
        restore-keys: |
          ${{ env.CACHE_KEY }}-

    - name: Install test dependencies
      run: ./ci/ci-install.bash

    - name: Test
      env:
        TESTS: ${{ matrix.suite }}
      run: ./ci/ci-script.bash

  lint-py:
    runs-on: ubuntu-22.04
    name: Lint Python
    env:
      CI_BUILD_STAGE_NAME: build
      CI_RUNS_ON: ubuntu-22.04
    steps:
    - name: Checkout
      uses: actions/checkout@v4
      with:
        path: repo

    - name: Install packages for build
      run: ./ci/ci-install.bash

    # We use specific version numbers, otherwise a Python package
    # update may add a warning and break our build
    - name: Install packages for lint
      run: sudo pip3 install pylint==3.0.2 ruff==0.1.3 clang sphinx sphinx_rtd_theme sphinxcontrib-spelling breathe ruff

    - name: Configure
      run: autoconf && ./configure --enable-longtests --enable-ccwarn

    - name: Lint
      run: make -k lint-py
